/**
 * helper_test.c - Helper函数测试程序
 *
 * 这个程序测试钩子框架中的helper函数功能
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>

#define TEST_FILE "/tmp/helper_test.txt"
#define TEST_DIR "/tmp/helper_test_dir"
#define TEST_LOG "/tmp/helper_test.log"
#define TEST_STRING "这是一个测试字符串，用于测试helper函数的功能"

// 测试文件操作
void test_file_operations() {
    printf("\n==== 文件操作测试 ====\n");
    
    // 写入测试文件
    FILE *f = fopen(TEST_FILE, "w");
    if (f) {
        fprintf(f, "%s\n", TEST_STRING);
        fclose(f);
        printf("创建了测试文件: %s\n", TEST_FILE);
    }
    
    // 打开并读取文件
    f = fopen(TEST_FILE, "r");
    if (f) {
        char buffer[256] = {0};
        if (fgets(buffer, sizeof(buffer), f)) {
            printf("读取文件内容: %s", buffer);
        }
        fclose(f);
    }
    
    // 创建测试目录
    mkdir(TEST_DIR, 0755);
    printf("创建了测试目录: %s\n", TEST_DIR);
    
    // 操作文件权限
    chmod(TEST_FILE, 0644);
    printf("修改了文件权限\n");
    
    // 删除测试目录和文件
    rmdir(TEST_DIR);
    unlink(TEST_FILE);
    printf("清理了测试文件和目录\n");
}

// 测试字符串处理
void test_string_operations() {
    printf("\n==== 字符串处理测试 ====\n");
    
    // 测试不同类型的字符串
    const char* examples[] = {
        "Hello, world!",
        "/path/to/some/file.txt",
        "user@example.com",
        "192.168.1.1",
        "http://example.com/index.html",
        "2021-01-01 12:34:56"
    };
    
    int num_examples = sizeof(examples) / sizeof(examples[0]);
    
    for (int i = 0; i < num_examples; i++) {
        printf("测试字符串 %d: %s\n", i+1, examples[i]);
        
        // 这些操作在钩子中将会调用helper函数
        if (strstr(examples[i], "file")) {
            printf("  - 包含'file'\n");
        }
        
        if (strncmp(examples[i], "http://", 7) == 0) {
            printf("  - 以'http://'开头\n");
        }
        
        if (strlen(examples[i]) > 0 && 
            examples[i][strlen(examples[i])-4] == '.' &&
            examples[i][strlen(examples[i])-3] == 'h' &&
            examples[i][strlen(examples[i])-2] == 't' &&
            examples[i][strlen(examples[i])-1] == 'm' &&
            examples[i][strlen(examples[i])] == 'l') {
            printf("  - 以'.html'结尾\n");
        }
    }
}

// 测试网络操作
void test_network_operations() {
    printf("\n==== 网络操作测试 ====\n");
    
    // 创建socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        printf("无法创建socket\n");
        return;
    }
    
    // 环回地址连接尝试
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
    
    printf("尝试连接到本地地址: 127.0.0.1:8080\n");
    
    // 连接会失败，但这没关系，我们只是想触发钩子
    connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
    // 尝试连接到外部地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(80);
    inet_pton(AF_INET, "8.8.8.8", &server_addr.sin_addr);
    
    printf("尝试连接到外部地址: 8.8.8.8:80\n");
    
    // 连接会失败，但这没关系，我们只是想触发钩子
    connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
    // 关闭socket
    close(sock);
}

// 测试进程操作
void test_process_operations() {
    printf("\n==== 进程操作测试 ====\n");
    
    // 获取当前进程信息
    printf("进程ID: %d\n", getpid());
    printf("父进程ID: %d\n", getppid());
    
    // 执行系统命令
    printf("执行系统命令: ls -la /tmp\n");
    system("ls -la /tmp");
    
    // 环境变量
    printf("\n环境变量:\n");
    printf("HOME = %s\n", getenv("HOME") ? getenv("HOME") : "(未设置)");
    printf("PATH = %s\n", getenv("PATH") ? getenv("PATH") : "(未设置)");
    printf("USER = %s\n", getenv("USER") ? getenv("USER") : "(未设置)");
}

// 测试辅助日志功能
void test_logging() {
    printf("\n==== 日志测试 ====\n");
    
    // 使用标准I/O进行日志记录
    FILE *log = fopen(TEST_LOG, "w");
    if (log) {
        fprintf(log, "这是一条日志消息，写入时间: %ld\n", time(NULL));
        fprintf(log, "此消息应该被hook_helpers.c中的helper函数捕获\n");
        fclose(log);
        printf("写入日志到: %s\n", TEST_LOG);
    }
    
    // 使用标准I/O读取日志
    log = fopen(TEST_LOG, "r");
    if (log) {
        char buffer[256];
        printf("日志内容:\n");
        while (fgets(buffer, sizeof(buffer), log)) {
            printf("  %s", buffer);
        }
        fclose(log);
    }
    
    // 删除测试日志
    unlink(TEST_LOG);
}

int main(int argc, char *argv[]) {
    printf("===== Helper函数测试程序 =====\n");
    printf("本程序测试各种操作以触发钩子框架helper函数\n\n");
    
    test_file_operations();
    test_string_operations();
    test_network_operations();
    test_process_operations();
    test_logging();
    
    printf("\n===== 测试完成 =====\n");
    return 0;
} 